I work on an e-reader app that sells books as IAPs. We have a lot - about 20,000 or so. This is over Apple's limit of 10,000 IAPs, so we've had to ask them to raise the limit for us more than once. Recently, at Apple's suggestion, we finally switched to a mechanism called Price Tiers, where instead of having one IAP item in App Store Connect for each of our products, we have one item per price level, so if the user buys product ID (in our system) 12345 for $5, instead of buying non-consumable IAP ID com.mycompany.myapp.12345, they buy consumable IAP ID com.mycompany.myapp.price_tier.5. In our system, we link the purchase to product 12345 at the time of receipt verification and everything works great.
But I have an issue that manifests when the user is using Ask to Buy or when receipt validation fails in our back-end, I don't call finishTransaction, and the transaction is retried later. The sequence is this:
User buys product 12345, which is com.mycompany.myapp.price_tier.5
The user has Ask to Buy enabled, so the transaction ends in the deferred state, and the IAP flow on the device is done for now
At some point later, the user gets permission for the purchase, and my SKPaymentQueue delegate gets notified of the transaction again in the background
But at the point of step 3, I have no way of knowing what product in our system the transaction is for. The same issue occurs if receipt verification fails on our end - I don't call finishTransaction, so StoreKit retries it later, but again at that point I don't know which one of our products to register to the user's account.
How do I make Ask to Buy (or any situation where I get notified of a transaction outside of a user-driven purchase) work with Price Tiers?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
WWDC 2021 session 10064 introduced UIButtonConfiguration, a new way to configure the visual appearance of buttons, for iOS 15. I've run into a surprising bit of behavior with its image setup: if you give it an image from an asset catalog that's bigger than the button's bounds, the image is sized too big for the button.
See the attached screenshot of an example app. The upper play icon is a button set up with setImage:forState:, and it sizes the image down as expected. The lower one is set up with UIButtonConfiguration, and is constrained to the same size (both buttons have a red border), but its image is too big.
How do I control the image sizing behavior here?
FB12358840 if any engineers look at this and think there could be an API improvement here.
I'm seeing some hang reports for my app in the Xcode organizer that boil down to [AAAttribution attributionTokenWithError:]. The docs for that method talk a lot about a request to Apple's services, but it looks like that's about passing the fetched token up to be decoded...but is the method also making a network request? Or is it doing something else that shouldn't be done on the main thread? If it wasn't main-thread safe I'd expect it to be documented as such, or for the Swift version to be async...
I have an app that currently supports as low as iOS 16. I'd like to add some app intents to it that allow customization using the WidgetConfigurationIntent API that's only available on iOS 17 and later. Is there a way to build an intent (or other kind of app extension) that requires a higher OS version than my main app's deployment target, and only surface it for those OS versions?
As of macOS Sequoia 15.1 (and probably earlier), in System Settings under Accessibility -> Display, there's a Text Size option that looks an awful lot like Dynamic Type on iOS:
I have an iOS app with robust support for Dynamic Type that I've brought to the Mac via Catalyst. Is there any way for me to opt this app into supporting this setting, maybe with some Info.plist key?
Calendar's Info.plist has a CTIgnoreUserFonts value set to true, but the Info.plist for Notes has no such value.
In the header for UIViewController, the method dismissViewControllerAnimated is declared like this:
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^ __nullable)(void))completion NS_SWIFT_DISABLE_ASYNC API_AVAILABLE(ios(5.0));
NS_SWIFT_DISABLE_ASYNC means that there's no async version exposed like there would normally be of a method that exposes a completion handler. Why is this? And is it unwise / unsafe for me to make my own async version of it using a continuation?
My use case is that I want a method that will sequentially dismiss all view controllers presented by a root view controller. So I could have this extension on UIViewController:
extension UIViewController {
func dismissAsync(animated: Bool) async {
await withCheckedContinuation { continuation in
self.dismiss(animated: animated) {
continuation.resume()
}
}
}
func dismissPresentedViewControllers() async {
while self.topPresentedViewController != self {
await self.topPresentedViewController.dismissAsync(animated: true)
}
}
var topPresentedViewController: UIViewController {
var result = self
while result.presentedViewController != nil {
result = result.presentedViewController!
}
return result
}
I've got a UIKit app that displays a lot of text, and we've completely turned off the system text selection menu and we show our own custom thing instead, to increase discoverability of our text selection actions. But now that iOS 26 can show the full menu even on iPhone, we're looking at switching back to the system menu.
It still shows a smaller horizontal-layout menu at first, and then you tap the > symbol to expand to the full menu. Is it possible to jump straight to the full menu, and skip the smaller horizontal one entirely?
I've got a Catalyst app that exposes some custom context menu items via the buildMenu API. When it runs on Tahoe, there's some weirdness with how the images in the menu items are sized. See attached screenshot below.
The three items on the bottom are using SF Symbols for their images, and the rest are using custom images from an asset catalog.
Is this a bug in Tahoe 26.0? Or should I be resizing my images before giving them to UIAction? If the latter, what should the size be, and is this documented somewhere or available from an API?
I want to offer a pay-as-you-go introductory offer for a subscription in my iOS app. But it's not clear to me what the actual pricing is if the offer is on a subscription whose period is more than 1 unit (2 month, 3 month, 6 month, etc).
For example, say I have a subscription that costs $20 per renewal and renews every 6 months. I set up an intro offer of the "Pay as you go" type (SKProductDiscountPaymentModePayAsYouGo) whose duration is 12 months and price is $10. Is the user going to get charged $10/month for 12 months (renewing 12 times), or $10 per 6 months for 12 months (renewing twice)?
The documentation - https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/implementing_introductory_offers_in_your_app?language=objc isn't all that clear on this. If I set this up with a local StoreKit test file - https://developer.apple.com/documentation/xcode/setting_up_storekit_testing_in_xcode?language=objc and try it in a simulator, the system purchase sheet appears to actually display it wrong. In my scenario above, the simulator shows a trial of "$10 per month for 2 months". I've filed this as FB8998598.
I have a UICollectionView that I feed data into using UICollectionViewDiffableDataSource. I want to display a scroll scrubber on the trailing edge of it, like I'd get if I implemented the data source methods indexTitlesForCollectionView and indexPathForIndexTitle. But the data source is the diffable data source object, and there's no property or closure on it to supply index titles as of iOS 15.
How are index titles supposed to work with UICollectionViewDiffableDataSource?
I have an iOS app that I'm looking to make available as a Catalyst app. I have various view controllers that I present using custom animations and presentation styles via UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning, UIPresentationController, et al.
Most of the view controllers I present with my custom styles are UINavigationController instances (or subclasses thereof). And when I build and run my Catalyst app on Ventura, the titles and bar items for the navigation items of the view controllers in the navigation stack get moved to the title bar of the application, and the navigation bar doesn't appear at all in the presented view controller.
Why is this happening, and how do I stop it? I've looked through the documentation for the APIs I mentioned above and tried setting various things that seemed like they could conceivably be relevant - UIPresentationController.shouldPresentInFullscreen, UIViewController.modalInPresentation, etc - and have had no luck.
I'm adding some text formatting support to an editable text view in my app, and I want to include bulleted lists. I specifically want to have the standard behavior where if you're typing a line of text in a list and press Enter, the next bullet item is automatically inserted.
This appears to somewhat work out-of-the-box with NSTextList on iOS 16, unless the line you're editing is at the very end of the document. This is apparent in the sample code for WWDC 2022 session 10090 (project is here):
Run that sample app and switch to the List tab
Put your cursor at the end of any line except the last one and press enter. You get a new list item, as expected.
Put your cursor at the end of the very last line and press Enter. You don't get a list item until you type something on that line.
I've likewise found that if I have this text in a text view:
Hello World\n\nList here\n
If I format the text List here as a bulleted list (by creating an NSMutableParagraphStyle with its textLists property set and adding it to the attributed string for that range) and press Enter at the end of the word Here, I get a new bullet item automatically. But if I do the same thing without having that last newline after Here, the new list item is not inserted.
How can I make the list auto-continuation behavior work at the end of the document?
One of the things discussed in Understanding the exception types in a crash report is the 0xdead10cc code under EXC_CRASH (SIGKILL):
0xdead10cc (pronounced “dead lock”). The operating system terminated the app because it held on to a file lock or SQLite database lock during suspension.
My app gets killed this way here and there, and it's been on my project list for some time to make the requisite changes to database connection handling to fix it. With an App Store build, as far as I know it just means the app cold-starts when launched instead of resuming, but in a TestFlight build it actually shows a crash reporter dialog.
Reports of this issue from TestFlight users got more frequent with a recent update that had the effect of keeping more SQLite handles open longer, and I realized that I personally have never seen a crash reporter dialog after fast-app-switching away from a TestFlight build on my device. And I use the TF build as my daily driver, and I use my app a lot.
My question is this: is it possible that the 0xdead10cc crash doesn't happen on Developer Mode devices?
WWDC 2021 session 10064 introduced UIButtonConfiguration, a new way to configure the visual appearance of buttons, for iOS 15. I'm now in the process of switching all my button setup over to UIButtonConfiguration, and I've run into one situation where it doesn't apply: rounding specific corners of the button. CALayer has the maskedCorners property that lets you round or mask specific corners but not others. In transferring border radius, border width, and border color styling over to UIButtonConfiguration via UIBackgroundConfiguration, I don't see an equivalent UI. Am I missing something?
For now, in cases when I need the maskedCorners functionality, I'm falling back to using the layer for border properties.